﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace PerformanceUtility.GameDebugTools
{
    /// <summary>
    /// Class for enqueuing events as they happen through the game.
    /// </summary>
    public class EventDisplay : DrawableGameComponent
    {
        /// <summary>
        /// Our reference to the debug manager.
        /// </summary>
        private DebugManager debugManager;

        /// <summary>
        /// Maximum number of events we track to display.
        /// </summary>
        private const int maxEvents = 100;

        /// <summary>
        /// The list of our latest events
        /// </summary>
        private List<string> events = new List<string>(maxEvents);

        public EventDisplay(Game game)
            : base(game)
        {
        }

        public override void Initialize()
        {
            // Get debug manager from game service.
            debugManager = Game.Services.GetService(typeof(DebugManager)) as DebugManager;

            if (debugManager == null)
                throw new InvalidOperationException("DebugManager is not registered.");

            // Register 'ed' command if debug command is registered as a service.
            IDebugCommandHost host = Game.Services.GetService(typeof(IDebugCommandHost))
                                                                as IDebugCommandHost;

            if (host != null)
            {
                host.RegisterCommand("ed", "Event Display", this.CommandExecute);
                Visible = false;
            }

            base.Initialize();
        }

        /// <summary>
        /// FPS command implementation.
        /// </summary>
        private void CommandExecute(IDebugCommandHost host, string command, IList<string> arguments)
        {
            if (arguments.Count == 0)
                Visible = !Visible;

            foreach (string arg in arguments)
            {
                switch (arg.ToLower())
                {
                    case "on":
                        Visible = true;
                        break;
                    case "off":
                        Visible = false;
                        break;
                }
            }
        }

        public void EnqueueDisplayEvent(string _eventDescription)
        {
            if (events.Count == maxEvents)
                events.RemoveAt(0);

            events.Add(_eventDescription);
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = debugManager.SpriteBatch;
            SpriteFont font = debugManager.DebugFont;

            // Draw
            spriteBatch.Begin();
            spriteBatch.Draw(debugManager.WhiteTexture, new Rectangle(0, 0, 400, 720), new Color(0, 0, 0, 128));
            for (int i = events.Count - 1; i >= 0; i--)
            {
                spriteBatch.DrawString(font, events[i], new Vector2(0, 720 - ((events.Count - i) * font.LineSpacing)), Color.White);
            }
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}
